//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package org_asset_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/org_dao"
	"atomgit.com/openlinksaas/api-server/dao/user_dao"
	"atomgit.com/openlinksaas/api-server/utils"
	"atomgit.com/openlinksaas/proto-gen-go.git/org_asset_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
)

func (apiImpl *OrgAssetApiImpl) AddAsset(ctx context.Context, req *org_asset_api.AddAssetRequest) (*org_asset_api.AddAssetResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_asset_api.AddAssetResponse{
			Code:   org_asset_api.AddAssetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_asset_api.AddAssetResponse{
			Code:   org_asset_api.AddAssetResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	selfMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_asset_api.AddAssetResponse{
			Code:   org_asset_api.AddAssetResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	exist, err := org_dao.AssetCateDao.Exist(ctx, req.OrgId, req.AssetCateId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_asset_api.AddAssetResponse{
			Code:   org_asset_api.AddAssetResponse_CODE_NO_ASSET_CATE,
			ErrMsg: "资产类别不存在",
		}, nil
	}

	if req.OwnerType == org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT {
		if !(sessionItem.UserId == orgItem.OwnerUserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.ParentDepartMentId == req.OwnerId && selfMemberItem.MemberPermInfo.ManageDepartMentAsset)) {
			return &org_asset_api.AddAssetResponse{
				Code:   org_asset_api.AddAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
		if req.OwnerId != "" {
			exist, err := org_dao.DepartMentDao.Exist(ctx, req.OrgId, req.OwnerId)
			if err != nil {
				return nil, err
			}
			if !exist {
				return &org_asset_api.AddAssetResponse{
					Code:   org_asset_api.AddAssetResponse_CODE_WRONG_OWNER,
					ErrMsg: "部门不存在",
				}, nil
			}
		}
	} else if req.OwnerType == org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_MEMBER {
		targetMemberItem := selfMemberItem
		if req.OwnerId != sessionItem.UserId {
			targetMemberItem, err = org_dao.MemberDao.Get(ctx, req.OrgId, req.OwnerId)
			if err != nil {
				return &org_asset_api.AddAssetResponse{
					Code:   org_asset_api.AddAssetResponse_CODE_WRONG_OWNER,
					ErrMsg: "部门成员不存在",
				}, nil
			}
		}
		if !(sessionItem.UserId == orgItem.OwnerUserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.MemberPermInfo.ManageSelfAsset && sessionItem.UserId == req.OwnerId) ||
			(selfMemberItem.MemberPermInfo.ManageDepartMentAsset && selfMemberItem.ParentDepartMentId == targetMemberItem.ParentDepartMentId)) {
			return &org_asset_api.AddAssetResponse{
				Code:   org_asset_api.AddAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	nowTime := time.Now().UnixNano() / 1e6
	assetId := uuid.NewString()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.AssetDao.Insert(sessCtx, &org_dao.AssetInfoDbItem{
			AssetId:      assetId,
			OrgId:        req.OrgId,
			AssetCateId:  req.AssetCateId,
			AssetNo:      req.AssetNo,
			AssetDesc:    req.AssetDesc,
			OwnerType:    uint32(req.OwnerType),
			OwnerId:      req.OwnerId,
			CreateTime:   nowTime,
			CreateUserId: sessionItem.UserId,
			UpdateTime:   nowTime,
			UpdateUserId: sessionItem.UserId,
		})
		if err != nil {
			return nil, err
		}
		count, err := org_dao.AssetDao.CountByCate(sessCtx, req.OrgId, req.AssetCateId)
		if err != nil {
			return nil, err
		}
		err = org_dao.AssetCateDao.UpdateAssetCount(sessCtx, req.OrgId, req.AssetCateId, count)
		if err != nil {
			return nil, err
		}
		if req.OwnerType == org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT {
			count, err := org_dao.AssetDao.CountByDepartMent(sessCtx, req.OrgId, req.OwnerId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateAssetCount(sessCtx, req.OrgId, req.OwnerId, count)
			if err != nil {
				return nil, err
			}
		}
		return &org_asset_api.AddAssetResponse{
			Code:    org_asset_api.AddAssetResponse_CODE_OK,
			AssetId: assetId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*org_asset_api.AddAssetResponse), nil
}

func (apiImpl *OrgAssetApiImpl) ListMemberAsset(ctx context.Context, req *org_asset_api.ListMemberAssetRequest) (*org_asset_api.ListMemberAssetResponse, error) {
	emptyList := []*org_asset_api.AssetInfo{}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_asset_api.ListMemberAssetResponse{
			Code:      org_asset_api.ListMemberAssetResponse_CODE_WRONG_SESSION,
			ErrMsg:    "会话不存在",
			AssetList: emptyList,
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_asset_api.ListMemberAssetResponse{
			Code:      org_asset_api.ListMemberAssetResponse_CODE_NO_ORG,
			ErrMsg:    "组织不存在",
			AssetList: emptyList,
		}, nil
	}
	curMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_asset_api.ListMemberAssetResponse{
			Code:      org_asset_api.ListMemberAssetResponse_CODE_NO_PERMISSION,
			ErrMsg:    "没有权限",
			AssetList: emptyList,
		}, nil
	}
	targetMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, req.MemberUserId)
	if err != nil {
		return &org_asset_api.ListMemberAssetResponse{
			Code:      org_asset_api.ListMemberAssetResponse_CODE_NO_PERMISSION,
			ErrMsg:    "没有权限",
			AssetList: emptyList,
		}, nil
	}
	//检查部门层级关系
	if !(orgItem.OwnerUserId == sessionItem.UserId || req.MemberUserId == sessionItem.UserId || curMemberItem.ParentDepartMentId == "") {
		include, err := utils.CheckIncludeDepartMent(ctx, req.OrgId, targetMemberItem.ParentDepartMentId, curMemberItem.ParentDepartMentId)
		if err != nil {
			return nil, err
		}
		if !include {
			return &org_asset_api.ListMemberAssetResponse{
				Code:      org_asset_api.ListMemberAssetResponse_CODE_NO_PERMISSION,
				ErrMsg:    "没有权限",
				AssetList: emptyList,
			}, nil
		}
	}
	//列出成员资产
	assetItemList, err := org_dao.AssetDao.ListByMember(ctx, req.OrgId, []string{req.MemberUserId})
	if err != nil {
		return nil, err
	}
	userIdList := []string{req.MemberUserId}
	for _, assetItem := range assetItemList {
		userIdList = append(userIdList, assetItem.CreateUserId)
		userIdList = append(userIdList, assetItem.UpdateUserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}
	//列出资产类别
	cateItemList, err := org_dao.AssetCateDao.List(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}
	cateItemMap := map[string]*org_dao.AssetCateInfoDbItem{}
	for _, cateItem := range cateItemList {
		cateItemMap[cateItem.AssetCateId] = cateItem
	}
	//生成结果
	assetList := []*org_asset_api.AssetInfo{}
	for _, assetItem := range assetItemList {
		assetInfo := assetItem.ToAssetInfo()
		createUserItem, ok := userItemMap[assetItem.CreateUserId]
		if ok {
			assetInfo.CreateDisplayName = createUserItem.BasicInfo.DisplayName
			assetInfo.CreateLogoUri = createUserItem.BasicInfo.LogoUri
		}
		updateUserItem, ok := userItemMap[assetItem.UpdateUserId]
		if ok {
			assetInfo.UpdateDisplayName = updateUserItem.BasicInfo.DisplayName
			assetInfo.UpdateLogoUri = updateUserItem.BasicInfo.LogoUri
		}
		cateItem, ok := cateItemMap[assetInfo.AssetCateId]
		if ok {
			assetInfo.CateName = cateItem.CateName
		}

		assetInfo.UserPerm = &org_asset_api.UserPerm{}
		if sessionItem.UserId == orgItem.OwnerUserId || curMemberItem.MemberPermInfo.ManageAllAsset {
			assetInfo.UserPerm.CanUpdate = true
			assetInfo.UserPerm.CanMoveInDepartMent = true
			assetInfo.UserPerm.CanMoveGlobal = true
			assetInfo.UserPerm.CanRemove = true
		}
		if curMemberItem.MemberPermInfo.ManageDepartMentAsset {
			assetInfo.UserPerm.CanUpdate = true
			assetInfo.UserPerm.CanMoveInDepartMent = true
			assetInfo.UserPerm.CanRemove = true
		} else if curMemberItem.MemberPermInfo.ManageSelfAsset && assetItem.OwnerId == sessionItem.UserId {
			assetInfo.UserPerm.CanUpdate = true
			assetInfo.UserPerm.CanRemove = true
		}

		ownerUserItem, ok := userItemMap[req.MemberUserId]
		if ok {
			assetInfo.OwnerName = ownerUserItem.BasicInfo.DisplayName
		}
		assetList = append(assetList, assetInfo)
	}

	return &org_asset_api.ListMemberAssetResponse{
		Code:      org_asset_api.ListMemberAssetResponse_CODE_OK,
		AssetList: assetList,
	}, nil
}

func (apiImpl *OrgAssetApiImpl) ListDepartMentAsset(ctx context.Context, req *org_asset_api.ListDepartMentAssetRequest) (*org_asset_api.ListDepartMentAssetResponse, error) {
	emptyList := []*org_asset_api.AssetInfo{}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_asset_api.ListDepartMentAssetResponse{
			Code:      org_asset_api.ListDepartMentAssetResponse_CODE_WRONG_SESSION,
			ErrMsg:    "会话不存在",
			AssetList: emptyList,
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_asset_api.ListDepartMentAssetResponse{
			Code:      org_asset_api.ListDepartMentAssetResponse_CODE_NO_ORG,
			ErrMsg:    "组织不存在",
			AssetList: emptyList,
		}, nil
	}
	curMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_asset_api.ListDepartMentAssetResponse{
			Code:      org_asset_api.ListDepartMentAssetResponse_CODE_NO_PERMISSION,
			ErrMsg:    "没有权限",
			AssetList: emptyList,
		}, nil
	}
	departMentName := "总部门"
	if req.DepartMentId != "" {
		departMentItem, err := org_dao.DepartMentDao.Get(ctx, req.OrgId, req.DepartMentId)
		if err != nil {
			return &org_asset_api.ListDepartMentAssetResponse{
				Code:      org_asset_api.ListDepartMentAssetResponse_CODE_NO_DEPART_MENT,
				ErrMsg:    "部门不存在",
				AssetList: emptyList,
			}, nil
		}
		departMentName = departMentItem.DepartMentName
	}
	//检查部门层级关系
	if !(orgItem.OwnerUserId == sessionItem.UserId || curMemberItem.ParentDepartMentId == "") {
		include, err := utils.CheckIncludeDepartMent(ctx, req.OrgId, req.DepartMentId, curMemberItem.ParentDepartMentId)
		if err != nil {
			return nil, err
		}
		if !include {
			return &org_asset_api.ListDepartMentAssetResponse{
				Code:      org_asset_api.ListDepartMentAssetResponse_CODE_NO_PERMISSION,
				ErrMsg:    "没有权限",
				AssetList: emptyList,
			}, nil
		}
	}

	//列出部门资产
	assetItemList, err := org_dao.AssetDao.ListByDepartMent(ctx, req.OrgId, req.DepartMentId)
	if err != nil {
		return nil, err
	}
	//列出成员资产
	memberItemList, err := org_dao.MemberDao.ListByDepartMent(ctx, req.OrgId, req.DepartMentId)
	if err != nil {
		return nil, err
	}
	memberUserIdList := []string{}
	for _, memberItem := range memberItemList {
		memberUserIdList = append(memberUserIdList, memberItem.MemberUserId)
	}
	memberAssetItemList, err := org_dao.AssetDao.ListByMember(ctx, req.OrgId, memberUserIdList)
	if err != nil {
		return nil, err
	}
	assetItemList = append(assetItemList, memberAssetItemList...)

	userIdList := []string{}
	for _, assetItem := range assetItemList {
		userIdList = append(userIdList, assetItem.CreateUserId)
		userIdList = append(userIdList, assetItem.UpdateUserId)
		if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_MEMBER) {
			userIdList = append(userIdList, assetItem.OwnerId)
		}
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}
	//列出资产类别
	cateItemList, err := org_dao.AssetCateDao.List(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}
	cateItemMap := map[string]*org_dao.AssetCateInfoDbItem{}
	for _, cateItem := range cateItemList {
		cateItemMap[cateItem.AssetCateId] = cateItem
	}
	//生成结果
	assetList := []*org_asset_api.AssetInfo{}
	for _, assetItem := range assetItemList {
		assetInfo := assetItem.ToAssetInfo()
		createUserItem, ok := userItemMap[assetItem.CreateUserId]
		if ok {
			assetInfo.CreateDisplayName = createUserItem.BasicInfo.DisplayName
			assetInfo.CreateLogoUri = createUserItem.BasicInfo.LogoUri
		}
		updateUserItem, ok := userItemMap[assetItem.UpdateUserId]
		if ok {
			assetInfo.UpdateDisplayName = updateUserItem.BasicInfo.DisplayName
			assetInfo.UpdateLogoUri = updateUserItem.BasicInfo.LogoUri
		}
		cateItem, ok := cateItemMap[assetInfo.AssetCateId]
		if ok {
			assetInfo.CateName = cateItem.CateName
		}
		assetInfo.UserPerm = &org_asset_api.UserPerm{}
		if sessionItem.UserId == orgItem.OwnerUserId || curMemberItem.MemberPermInfo.ManageAllAsset {
			assetInfo.UserPerm.CanUpdate = true
			assetInfo.UserPerm.CanMoveInDepartMent = true
			assetInfo.UserPerm.CanMoveGlobal = true
			assetInfo.UserPerm.CanRemove = true
		}
		if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT) {
			assetInfo.OwnerName = departMentName
			if curMemberItem.MemberPermInfo.ManageDepartMentPerm && curMemberItem.ParentDepartMentId == assetInfo.OwnerId {
				assetInfo.UserPerm.CanUpdate = true
				assetInfo.UserPerm.CanMoveInDepartMent = true
				assetInfo.UserPerm.CanRemove = true
			}
		} else if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_MEMBER) {
			ownerUserItem, ok := userItemMap[assetInfo.OwnerId]
			if ok {
				assetInfo.OwnerName = ownerUserItem.BasicInfo.DisplayName
			}
			if curMemberItem.MemberPermInfo.ManageDepartMentAsset {
				assetInfo.UserPerm.CanUpdate = true
				assetInfo.UserPerm.CanMoveInDepartMent = true
				assetInfo.UserPerm.CanRemove = true
			} else if curMemberItem.MemberPermInfo.ManageSelfAsset && assetItem.OwnerId == sessionItem.UserId {
				assetInfo.UserPerm.CanUpdate = true
				assetInfo.UserPerm.CanRemove = true
			}
		}
		assetList = append(assetList, assetInfo)
	}

	return &org_asset_api.ListDepartMentAssetResponse{
		Code:      org_asset_api.ListDepartMentAssetResponse_CODE_OK,
		AssetList: assetList,
	}, nil
}

func (apiImpl *OrgAssetApiImpl) UpdateBaseForAsset(ctx context.Context, req *org_asset_api.UpdateBaseForAssetRequest) (*org_asset_api.UpdateBaseForAssetResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_asset_api.UpdateBaseForAssetResponse{
			Code:   org_asset_api.UpdateBaseForAssetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_asset_api.UpdateBaseForAssetResponse{
			Code:   org_asset_api.UpdateBaseForAssetResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	selfMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_asset_api.UpdateBaseForAssetResponse{
			Code:   org_asset_api.UpdateBaseForAssetResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	assetItem, err := org_dao.AssetDao.Get(ctx, req.OrgId, req.AssetId)
	if err != nil {
		return &org_asset_api.UpdateBaseForAssetResponse{
			Code:   org_asset_api.UpdateBaseForAssetResponse_CODE_NO_ASSET,
			ErrMsg: "资产不存在",
		}, nil
	}
	if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT) {
		if !(orgItem.OwnerUserId == sessionItem.UserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.MemberPermInfo.ManageDepartMentAsset && selfMemberItem.ParentDepartMentId == assetItem.OwnerId)) {
			return &org_asset_api.UpdateBaseForAssetResponse{
				Code:   org_asset_api.UpdateBaseForAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	} else if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_MEMBER) {
		targetMemberItem := selfMemberItem
		if sessionItem.UserId != assetItem.OwnerId {
			targetMemberItem, err = org_dao.MemberDao.Get(ctx, req.OrgId, assetItem.OwnerId)
			if err != nil {
				return nil, err
			}
		}
		if !(orgItem.OwnerUserId == sessionItem.UserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.MemberPermInfo.ManageDepartMentAsset && selfMemberItem.ParentDepartMentId == targetMemberItem.ParentDepartMentId) ||
			(selfMemberItem.MemberPermInfo.ManageSelfAsset && sessionItem.UserId == targetMemberItem.MemberUserId)) {
			return &org_asset_api.UpdateBaseForAssetResponse{
				Code:   org_asset_api.UpdateBaseForAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.AssetDao.UpdateBaseInfo(sessCtx, req.OrgId, req.AssetId, req.AssetNo, req.AssetDesc, sessionItem.UserId, nowTime)
		if err != nil {
			return nil, err
		}
		return &org_asset_api.UpdateBaseForAssetResponse{
			Code: org_asset_api.UpdateBaseForAssetResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*org_asset_api.UpdateBaseForAssetResponse), nil
}

func (apiImpl *OrgAssetApiImpl) UpdateCateForAsset(ctx context.Context, req *org_asset_api.UpdateCateForAssetRequest) (*org_asset_api.UpdateCateForAssetResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_asset_api.UpdateCateForAssetResponse{
			Code:   org_asset_api.UpdateCateForAssetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_asset_api.UpdateCateForAssetResponse{
			Code:   org_asset_api.UpdateCateForAssetResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	selfMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_asset_api.UpdateCateForAssetResponse{
			Code:   org_asset_api.UpdateCateForAssetResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := org_dao.AssetCateDao.Exist(ctx, req.OrgId, req.AssetCateId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_asset_api.UpdateCateForAssetResponse{
			Code:   org_asset_api.UpdateCateForAssetResponse_CODE_NO_ASSET_CATE,
			ErrMsg: "资产类别不存在",
		}, nil
	}

	assetItem, err := org_dao.AssetDao.Get(ctx, req.OrgId, req.AssetId)
	if err != nil {
		return &org_asset_api.UpdateCateForAssetResponse{
			Code:   org_asset_api.UpdateCateForAssetResponse_CODE_NO_ASSET,
			ErrMsg: "资产不存在",
		}, nil
	}
	if assetItem.AssetCateId == req.AssetCateId { //不用修改
		return &org_asset_api.UpdateCateForAssetResponse{
			Code: org_asset_api.UpdateCateForAssetResponse_CODE_OK,
		}, nil
	}

	if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT) {
		if !(orgItem.OwnerUserId == sessionItem.UserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.MemberPermInfo.ManageDepartMentAsset && selfMemberItem.ParentDepartMentId == assetItem.OwnerId)) {
			return &org_asset_api.UpdateCateForAssetResponse{
				Code:   org_asset_api.UpdateCateForAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	} else if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_MEMBER) {
		targetMemberItem := selfMemberItem
		if sessionItem.UserId != assetItem.OwnerId {
			targetMemberItem, err = org_dao.MemberDao.Get(ctx, req.OrgId, assetItem.OwnerId)
			if err != nil {
				return nil, err
			}
		}
		if !(orgItem.OwnerUserId == sessionItem.UserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.MemberPermInfo.ManageDepartMentAsset && selfMemberItem.ParentDepartMentId == targetMemberItem.ParentDepartMentId) ||
			(selfMemberItem.MemberPermInfo.ManageSelfAsset && sessionItem.UserId == targetMemberItem.MemberUserId)) {
			return &org_asset_api.UpdateCateForAssetResponse{
				Code:   org_asset_api.UpdateCateForAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.AssetDao.UpdateCate(sessCtx, req.OrgId, req.AssetId, req.AssetCateId, sessionItem.UserId, nowTime)
		if err != nil {
			return nil, err
		}
		//调整旧类别数量
		{
			count, err := org_dao.AssetDao.CountByCate(sessCtx, req.OrgId, assetItem.AssetCateId)
			if err != nil {
				return nil, err
			}
			err = org_dao.AssetCateDao.UpdateAssetCount(sessCtx, req.OrgId, assetItem.AssetCateId, count)
			if err != nil {
				return nil, err
			}
		}
		//调整新类别数量
		{
			count, err := org_dao.AssetDao.CountByCate(sessCtx, req.OrgId, req.AssetCateId)
			if err != nil {
				return nil, err
			}
			err = org_dao.AssetCateDao.UpdateAssetCount(sessCtx, req.OrgId, req.AssetCateId, count)
			if err != nil {
				return nil, err
			}
		}
		return &org_asset_api.UpdateCateForAssetResponse{
			Code: org_asset_api.UpdateCateForAssetResponse_CODE_OK,
		}, nil
	})

	if err != nil {
		return nil, err
	}
	return ret.(*org_asset_api.UpdateCateForAssetResponse), nil
}

func (apiImpl *OrgAssetApiImpl) MoveAsset(ctx context.Context, req *org_asset_api.MoveAssetRequest) (*org_asset_api.MoveAssetResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_asset_api.MoveAssetResponse{
			Code:   org_asset_api.MoveAssetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_asset_api.MoveAssetResponse{
			Code:   org_asset_api.MoveAssetResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	selfMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_asset_api.MoveAssetResponse{
			Code:   org_asset_api.MoveAssetResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	assetItem, err := org_dao.AssetDao.Get(ctx, req.OrgId, req.AssetId)
	if err != nil {
		return &org_asset_api.MoveAssetResponse{
			Code:   org_asset_api.MoveAssetResponse_CODE_NO_ASSET,
			ErrMsg: "资产不存在",
		}, nil
	}

	if assetItem.OwnerType == uint32(req.OwnerType) && assetItem.OwnerId == req.OwnerId { //不需要修改
		return &org_asset_api.MoveAssetResponse{
			Code: org_asset_api.MoveAssetResponse_CODE_OK,
		}, nil
	}

	if req.OwnerType == org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT {
		if req.OwnerId != "" {
			exist, err := org_dao.DepartMentDao.Exist(ctx, req.OrgId, req.OwnerId)
			if err != nil {
				return nil, err
			}
			if !exist {
				return &org_asset_api.MoveAssetResponse{
					Code:   org_asset_api.MoveAssetResponse_CODE_WRONG_OWNER,
					ErrMsg: "目标部门不存在",
				}, nil
			}
		}
		if !(sessionItem.UserId == orgItem.OwnerUserId || selfMemberItem.MemberPermInfo.ManageAllAsset) {
			return &org_asset_api.MoveAssetResponse{
				Code:   org_asset_api.MoveAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	} else if req.OwnerType == org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_MEMBER {
		targetMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, req.OwnerId)
		if err != nil {
			return &org_asset_api.MoveAssetResponse{
				Code:   org_asset_api.MoveAssetResponse_CODE_WRONG_OWNER,
				ErrMsg: "目标成员不存在",
			}, nil
		}

		if !(sessionItem.UserId == orgItem.OwnerUserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.MemberPermInfo.ManageDepartMentAsset && selfMemberItem.ParentDepartMentId == targetMemberItem.ParentDepartMentId)) {
			return &org_asset_api.MoveAssetResponse{
				Code:   org_asset_api.MoveAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.AssetDao.UpdateOwner(sessCtx, req.OrgId, req.AssetId, uint32(req.OwnerType), req.OwnerId, sessionItem.UserId, nowTime)
		if err != nil {
			return nil, err
		}
		if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT) {
			count, err := org_dao.AssetDao.CountByDepartMent(sessCtx, req.OrgId, assetItem.OwnerId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateAssetCount(sessCtx, req.OrgId, assetItem.OwnerId, count)
			if err != nil {
				return nil, err
			}
		}
		if req.OwnerType == org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT {
			count, err := org_dao.AssetDao.CountByDepartMent(sessCtx, req.OrgId, req.OwnerId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateAssetCount(sessCtx, req.OrgId, req.OwnerId, count)
			if err != nil {
				return nil, err
			}
		}
		return &org_asset_api.MoveAssetResponse{
			Code: org_asset_api.MoveAssetResponse_CODE_OK,
		}, nil
	})

	if err != nil {
		return nil, err
	}
	return ret.(*org_asset_api.MoveAssetResponse), nil
}

func (apiImpl *OrgAssetApiImpl) RemoveAsset(ctx context.Context, req *org_asset_api.RemoveAssetRequest) (*org_asset_api.RemoveAssetResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_asset_api.RemoveAssetResponse{
			Code:   org_asset_api.RemoveAssetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_asset_api.RemoveAssetResponse{
			Code:   org_asset_api.RemoveAssetResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	selfMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_asset_api.RemoveAssetResponse{
			Code:   org_asset_api.RemoveAssetResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	assetItem, err := org_dao.AssetDao.Get(ctx, req.OrgId, req.AssetId)
	if err != nil { //资产不存在
		return &org_asset_api.RemoveAssetResponse{
			Code: org_asset_api.RemoveAssetResponse_CODE_OK,
		}, nil
	}
	if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT) {
		if !(orgItem.OwnerUserId == sessionItem.UserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.MemberPermInfo.ManageDepartMentAsset && selfMemberItem.ParentDepartMentId == assetItem.OwnerId)) {
			return &org_asset_api.RemoveAssetResponse{
				Code:   org_asset_api.RemoveAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	} else if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_MEMBER) {
		targetMemberItem := selfMemberItem
		if sessionItem.UserId != assetItem.OwnerId {
			targetMemberItem, err = org_dao.MemberDao.Get(ctx, req.OrgId, assetItem.OwnerId)
			if err != nil {
				return nil, err
			}
		}
		if !(orgItem.OwnerUserId == sessionItem.UserId || selfMemberItem.MemberPermInfo.ManageAllAsset ||
			(selfMemberItem.MemberPermInfo.ManageDepartMentAsset && selfMemberItem.ParentDepartMentId == targetMemberItem.ParentDepartMentId) ||
			(selfMemberItem.MemberPermInfo.ManageSelfAsset && sessionItem.UserId == targetMemberItem.MemberUserId)) {
			return &org_asset_api.RemoveAssetResponse{
				Code:   org_asset_api.RemoveAssetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.AssetDao.Remove(sessCtx, req.OrgId, req.AssetId)
		if err != nil {
			return nil, err
		}
		//调整类别数量
		count, err := org_dao.AssetDao.CountByCate(sessCtx, req.OrgId, assetItem.AssetCateId)
		if err != nil {
			return nil, err
		}
		err = org_dao.AssetCateDao.UpdateAssetCount(sessCtx, req.OrgId, assetItem.AssetCateId, count)
		if err != nil {
			return nil, err
		}
		if assetItem.OwnerType == uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT) {
			count, err = org_dao.AssetDao.CountByDepartMent(sessCtx, req.OrgId, assetItem.OwnerId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateAssetCount(sessCtx, req.OrgId, assetItem.OwnerId, count)
			if err != nil {
				return nil, err
			}
		}
		return &org_asset_api.RemoveAssetResponse{
			Code: org_asset_api.RemoveAssetResponse_CODE_OK,
		}, nil
	})

	if err != nil {
		return nil, err
	}
	return ret.(*org_asset_api.RemoveAssetResponse), nil
}
